import pygame
import sys
import math

# 引入自定义关卡资源
from 关卡.tuixiangzi01 import levels_all
# 引入初始化界面
from 菜单.init_menu import draw_menu, handle_menu_click
# 引入游戏模型
from 模型.model import *

# 全局变量
menu_buttons = []  # 存储菜单按钮
undo_button_rect = None  # 初始化撤回按钮矩形
restart_button_rect = None  # 初始化重新开始按钮矩形
background_cache = None  # 背景缓存，避免重复绘制
last_game_state = None  # 记录上次的游戏状态

# 初始化pygame
pygame.init()

# 定义常量
TILE_SIZE = 36  # 每个格子大小
LEVEL_WIDTH = 16  # 关卡宽度（格子数）
LEVEL_HEIGHT = 16  # 关卡高度（格子数）
INFO_PANEL_WIDTH = 240  # 右侧信息面板宽度

# 计算窗口大小
SCREEN_WIDTH = TILE_SIZE * LEVEL_WIDTH
SCREEN_HEIGHT = TILE_SIZE * LEVEL_HEIGHT
TOTAL_WIDTH = SCREEN_WIDTH + INFO_PANEL_WIDTH

# 定义颜色
BG_COLOR = (20, 20, 20)
INFO_BG_COLOR = (30, 30, 30)
TEXT_COLOR = (255, 255, 255)
MENU_BG_COLOR = (40, 40, 40)
MENU_HIGHLIGHT_COLOR = (255, 255, 255)  # 选中时白色
MENU_NORMAL_COLOR = (128, 128, 128)     # 未选中时暗色
BUTTON_BG_COLOR = (60, 60, 60)
BUTTON_HOVER_COLOR = (80, 80, 80)
BUTTON_BORDER_COLOR = (100, 100, 100)

# 创建窗口
screen = pygame.display.set_mode((TOTAL_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("推箱子游戏")

# 创建时钟对象来控制帧率
clock = pygame.time.Clock()

# 加载字体
default_font = pygame.font.SysFont("SimSun, Microsoft YaHei", 20)
title_font = pygame.font.SysFont("SimSun, Microsoft YaHei", 24)
large_title_font = pygame.font.SysFont("SimSun, Microsoft YaHei", 36)
button_font = pygame.font.SysFont("SimSun, Microsoft YaHei", 24)
small_font = pygame.font.SysFont("SimSun, Microsoft YaHei", 16)

# 游戏元素常量已在model.py中定义

# 游戏状态常量
GAME_STATE_MENU = 0
GAME_STATE_PLAYING = 1
GAME_STATE_PAUSED = 2
GAME_STATE_RULES = 3
GAME_STATE_EXIT_CONFIRM = 4
GAME_STATE_VICTORY = 5  # 游戏胜利弹窗状态

# 关卡初始化
levels = levels_all
current_level = 0

# 游戏状态变量
game_state = GAME_STATE_MENU  # 从菜单开始
selected_menu_item = 0
selected_pause_item = 0
selected_level = 0
rules_scroll_offset = 0  # 规则滚动偏移量
exit_confirm_selection = 0  # 退出确认选择
rules_from_pause = False  # 标记规则界面是否从暂停菜单进入
exit_from_pause = False  # 标记退出确认是否从暂停菜单进入
exit_from_menu = False  # 标记退出确认是否从菜单界面进入

# 鼠标悬停状态变量
hover_menu_item = -1  # 主菜单悬停项
hover_pause_item = -1  # 暂停菜单悬停项
hover_exit_option = -1  # 退出确认悬停选项
hover_level_button = -1  # 关卡按钮悬停项
hover_victory_option = -1  # 胜利弹窗悬停选项
hover_undo_button = False  # 撤回按钮悬停状态
hover_restart_button = False  # 重新开始按钮悬停状态

# 按钮按下状态变量
pressed_undo = False
pressed_restart = False
pressed_level_button = -1  # -1表示没有关卡按钮被按下

# 滚动条拖动状态变量
scrollbar_dragging = False  # 是否正在拖动滚动条
drag_start_y = 0  # 拖动开始时的鼠标Y坐标
drag_start_offset = 0  # 拖动开始时的滚动偏移量

# 关卡按钮相关变量
level_buttons = []  # 存储关卡按钮的矩形和索引
hover_level_button = -1  # 当前悬停的关卡索引

undo_stack = []

def get_rules_content():
    """获取游戏说明内容"""
    return [
        "游戏目标",
        "将所有箱子推到目标点上，完成关卡挑战",
        "",
        "游戏元素",
        "• 红色小人：玩家角色，可以在地图上移动",
        "• 棕色箱子：需要推动的箱子，带有X标记",
        "• 黄色方块：目标点，箱子需要推到这里",
        "• 灰色方块：墙壁，不可通过",
        "• 浅色方块：通道，可以自由移动",
        "",
        "操作说明",
        "• ↑ / W: 向上移动",
        "• ↓ / S: 向下移动", 
        "• ← / A: 向左移动",
        "• → / D: 向右移动",
        "• R: 重玩本关",
        "• ESC: 暂停游戏",
        "• P: 返回上一关",
        "• N: 进入下一关",
        "• Ctrl+←/→: 选择关卡",
        "• Enter: 确认关卡选择",
        "",
        "游戏规则",
        "• 玩家只能推动箱子，不能拉动",
        "• 箱子不能穿过墙壁或其他箱子",
        "• 所有箱子都推到目标点才算过关",
        "• 如果箱子被推到死角无法移动，需要重新开始",
        "",
        "游戏技巧",
        "• 注意箱子的移动顺序，避免死锁",
        "• 避免将箱子推到死角或墙角",
        "• 合理规划移动路径，减少不必要的移动",
        "• 观察目标点的分布，制定策略",
        "• 先移动远离目标的箱子，再处理近处的",
        "",
        "界面说明",
        "• 右侧面板显示当前关卡信息和统计数据",
        "• 可以随时切换关卡进行游戏",
        "• 暂停菜单可以查看说明或退出游戏",
        "• 游戏胜利后会显示移动步数统计",
        "• 支持关卡选择和快速重玩功能"
    ]

# 获取玩家初始位置
def find_player(level):
    height = len(level)
    width = len(level[0])
    for y in range(height):
        for x in range(width):
            if level[y][x] == PLAYER or level[y][x] == PLAYER_ON_TARGET:  # 玩家或玩家在目标点上
                return (x, y)
    return None

# 重置当前关卡
def reset_level():
    global level, player_pos, moves
    # 清空撤回栈
    undo_stack.clear()
    level = [row[:] for row in levels[current_level]]
    # 重新设置玩家位置
    player_pos = find_player(level)
    if player_pos is None:
        # 如果没有找到玩家，设置默认位置（左上角第一个空地）
        height = len(level)
        width = len(level[0])
        for y in range(height):
            for x in range(width):
                if level[y][x] == PATH:
                    player_pos = (x, y)
                    level[y][x] = PLAYER
                    break
            if player_pos is not None:
                break
    moves = 0
    return level, player_pos

# 初始化第一个关卡
level, player_pos = reset_level()
moves = 0

# 撤回功能实现

def save_undo_state():
    # 保存当前关卡状态到撤回栈
    import copy
    undo_stack.append((copy.deepcopy(level), player_pos, moves))
    # 限制撤回栈长度，防止内存溢出
    if len(undo_stack) > 100:
        undo_stack.pop(0)

def undo_move():
    global level, player_pos, moves
    if undo_stack:
        state = undo_stack.pop()
        level, player_pos, moves = state
        # 清除背景缓存，确保界面正确更新
        global background_cache
        background_cache = None
        draw_game()


# 游戏主循环
running = True



def draw_pause_menu():
    """绘制暂停菜单界面"""
    global background_cache, last_game_state
    
    # 检查是否需要重新绘制背景
    if background_cache is None or last_game_state != GAME_STATE_PLAYING:
        # 先绘制游戏界面作为背景
        draw_game()
        # 缓存背景
        background_cache = screen.copy()
        last_game_state = GAME_STATE_PLAYING
    else:
        # 使用缓存的背景
        screen.blit(background_cache, (0, 0))
    
    # 创建半透明遮罩
    overlay = pygame.Surface((TOTAL_WIDTH, SCREEN_HEIGHT))
    overlay.set_alpha(128)
    overlay.fill((0, 0, 0))
    screen.blit(overlay, (0, 0))
    
    # 绘制暂停菜单背景
    menu_rect = pygame.Rect(TOTAL_WIDTH // 2 - 150, SCREEN_HEIGHT // 2 - 150, 300, 300)
    pygame.draw.rect(screen, MENU_BG_COLOR, menu_rect)
    pygame.draw.rect(screen, TEXT_COLOR, menu_rect, 3)
    
    # 暂停标题
    pause_text = title_font.render("游戏暂停", True, TEXT_COLOR)
    pause_rect = pause_text.get_rect(center=(TOTAL_WIDTH // 2, SCREEN_HEIGHT // 2 - 100))
    screen.blit(pause_text, pause_rect)
    
    # 菜单选项
    pause_items = ["继续游戏", "游戏规则", "退出游戏"]
    
    for i, item in enumerate(pause_items):
        # 根据悬停状态选择颜色
        color = MENU_HIGHLIGHT_COLOR if i == hover_pause_item else MENU_NORMAL_COLOR
        
        text = default_font.render(item, True, color)
        text_rect = text.get_rect(center=(TOTAL_WIDTH // 2, SCREEN_HEIGHT // 2 - 30 + i * 50))
        screen.blit(text, text_rect)
    
    pygame.display.flip()

def draw_exit_confirm():
    """绘制退出确认界面"""
    global background_cache, last_game_state
    
    # 根据来源界面绘制不同的背景
    if exit_from_menu:
        # 从菜单界面退出，绘制菜单背景
        if background_cache is None or last_game_state != GAME_STATE_MENU:
            draw_menu(screen, TOTAL_WIDTH, SCREEN_HEIGHT)
            background_cache = screen.copy()
            last_game_state = GAME_STATE_MENU
        else:
            screen.blit(background_cache, (0, 0))
    else:
        # 从游戏界面退出，绘制游戏背景
        if background_cache is None or last_game_state != GAME_STATE_PLAYING:
            draw_game()
            background_cache = screen.copy()
            last_game_state = GAME_STATE_PLAYING
        else:
            screen.blit(background_cache, (0, 0))
    
    # 创建半透明遮罩
    overlay = pygame.Surface((TOTAL_WIDTH, SCREEN_HEIGHT))
    overlay.set_alpha(128)
    overlay.fill((0, 0, 0))
    screen.blit(overlay, (0, 0))
    
    # 绘制确认对话框背景
    confirm_rect = pygame.Rect(TOTAL_WIDTH // 2 - 200, SCREEN_HEIGHT // 2 - 100, 400, 200)
    pygame.draw.rect(screen, MENU_BG_COLOR, confirm_rect)
    pygame.draw.rect(screen, TEXT_COLOR, confirm_rect, 3)
    
    # 确认标题
    confirm_text = title_font.render("确认退出游戏？", True, TEXT_COLOR)
    confirm_rect_text = confirm_text.get_rect(center=(TOTAL_WIDTH // 2, SCREEN_HEIGHT // 2 - 50))
    screen.blit(confirm_text, confirm_rect_text)
    
    # 选项
    options = ["是", "否"]
    for i, option in enumerate(options):
        # 根据悬停状态选择颜色
        color = MENU_HIGHLIGHT_COLOR if i == hover_exit_option else MENU_NORMAL_COLOR
        
        text = default_font.render(option, True, color)
        text_rect = text.get_rect(center=(TOTAL_WIDTH // 2 - 50 + i * 100, SCREEN_HEIGHT // 2 + 20))
        screen.blit(text, text_rect)
    
    pygame.display.flip()

def draw_victory_popup():
    """绘制游戏胜利弹窗界面"""
    global background_cache, last_game_state
    
    # 检查是否需要重新绘制背景
    if background_cache is None or last_game_state != GAME_STATE_PLAYING:
        # 先绘制游戏界面作为背景
        draw_game()
        # 缓存背景
        background_cache = screen.copy()
        last_game_state = GAME_STATE_PLAYING
    else:
        # 使用缓存的背景
        screen.blit(background_cache, (0, 0))
    
    # 创建半透明遮罩
    overlay = pygame.Surface((TOTAL_WIDTH, SCREEN_HEIGHT))
    overlay.set_alpha(128)
    overlay.fill((0, 0, 0))
    screen.blit(overlay, (0, 0))
    
    # 绘制胜利弹窗背景
    popup_rect = pygame.Rect(TOTAL_WIDTH // 2 - 250, SCREEN_HEIGHT // 2 - 200, 500, 400)
    pygame.draw.rect(screen, MENU_BG_COLOR, popup_rect)
    pygame.draw.rect(screen, TEXT_COLOR, popup_rect, 3)
    
    # 胜利标题
    victory_text = large_title_font.render("🎉 恭喜通关！", True, (255, 215, 0))  # 金色
    victory_rect = victory_text.get_rect(center=(TOTAL_WIDTH // 2, SCREEN_HEIGHT // 2 - 120))
    screen.blit(victory_text, victory_rect)
    
    # 关卡信息
    level_text = title_font.render(f"第 {current_level + 1} 关", True, TEXT_COLOR)
    level_rect = level_text.get_rect(center=(TOTAL_WIDTH // 2, SCREEN_HEIGHT // 2 - 70))
    screen.blit(level_text, level_rect)
    
    # 移动步数
    moves_text = title_font.render(f"移动步数：{moves}", True, TEXT_COLOR)
    moves_rect = moves_text.get_rect(center=(TOTAL_WIDTH // 2, SCREEN_HEIGHT // 2 - 20))
    screen.blit(moves_text, moves_rect)
    
    # 是否进入下一关的提示
    next_text = default_font.render("是否进入下一关？", True, TEXT_COLOR)
    next_rect = next_text.get_rect(center=(TOTAL_WIDTH // 2, SCREEN_HEIGHT // 2 + 30))
    screen.blit(next_text, next_rect)
    
    # 选项按钮
    options = ["是", "否"]
    for i, option in enumerate(options):
        # 根据悬停状态选择颜色
        color = MENU_HIGHLIGHT_COLOR if i == hover_victory_option else MENU_NORMAL_COLOR
        
        text = button_font.render(option, True, color)
        text_rect = text.get_rect(center=(TOTAL_WIDTH // 2 - 80 + i * 160, SCREEN_HEIGHT // 2 + 100))
        screen.blit(text, text_rect)
    
    pygame.display.flip()

def draw_rules():
    """绘制游戏规则界面（带滚动功能）"""
    global rules_scroll_offset
    screen.fill(BG_COLOR)
    
    # 标题
    title_text = title_font.render("游戏说明", True, TEXT_COLOR)
    title_rect = title_text.get_rect(center=(TOTAL_WIDTH // 2, 50))
    screen.blit(title_text, title_rect)
    
    # 返回按钮 - 与标题水平对齐
    button_width = 80
    button_height = 30
    button_x = 20
    button_y = 35  # 与标题水平对齐
    
    # 检查鼠标悬停状态
    mouse_x, mouse_y = pygame.mouse.get_pos()
    is_hover = (button_x <= mouse_x <= button_x + button_width and 
                button_y <= mouse_y <= button_y + button_height)
    
    # 绘制返回按钮
    bg_color = BUTTON_HOVER_COLOR if is_hover else BUTTON_BG_COLOR
    border_color = MENU_HIGHLIGHT_COLOR if is_hover else BUTTON_BORDER_COLOR
    text_color = MENU_HIGHLIGHT_COLOR if is_hover else MENU_NORMAL_COLOR
    
    button_rect = pygame.Rect(button_x, button_y, button_width, button_height)
    pygame.draw.rect(screen, bg_color, button_rect)
    pygame.draw.rect(screen, border_color, button_rect, 2)
    
    # 绘制返回按钮文字
    back_button_text = small_font.render("返回", True, text_color)
    back_button_text_rect = back_button_text.get_rect(center=button_rect.center)
    screen.blit(back_button_text, back_button_text_rect)
    
    # 游戏说明内容
    rules = get_rules_content()
    
    # 计算说明内容的总高度（调整行间距）
    rule_height = len(rules) * 35  # 增加行间距
    max_scroll = max(0, rule_height - (SCREEN_HEIGHT - 200))  # 200是标题和底部提示的空间
    
    # 限制滚动范围
    rules_scroll_offset = max(0, min(rules_scroll_offset, max_scroll))
    
    # 直接在主屏幕上绘制说明内容，不使用Surface
    y_pos = 100
    for i, rule in enumerate(rules):
        # 计算实际显示位置
        display_y = y_pos - rules_scroll_offset
        
        # 只绘制在可见区域内的内容
        if display_y + 35 > 100 and display_y < SCREEN_HEIGHT - 50:
            if rule.startswith("•"):
                # 缩进说明项
                text = default_font.render(rule, True, TEXT_COLOR)
                screen.blit(text, (50, display_y))  # 增加缩进
            elif rule == "":
                # 空行，增加间距
                pass
            elif i > 0 and rules[i-1] == "" and not rule.startswith("•"):
                # 这是标题行（前面有空行，且不以•开头）
                text = title_font.render(rule, True, TEXT_COLOR)
                screen.blit(text, (30, display_y))  # 标题左对齐
            else:
                # 普通文本
                text = default_font.render(rule, True, TEXT_COLOR)
                screen.blit(text, (30, display_y))  # 左对齐
        
        y_pos += 35  # 增加行间距
    
    # 绘制滚动条（如果有内容超出）
    if max_scroll > 0:
        scrollbar_width = 10
        scrollbar_height = (SCREEN_HEIGHT - 200) * (SCREEN_HEIGHT - 200) / rule_height
        scrollbar_y = 100 + (rules_scroll_offset / max_scroll) * ((SCREEN_HEIGHT - 200) - scrollbar_height)
        
        # 滚动条背景
        pygame.draw.rect(screen, (60, 60, 60), (TOTAL_WIDTH - 30, 100, scrollbar_width, SCREEN_HEIGHT - 200))
        # 滚动条滑块
        pygame.draw.rect(screen, TEXT_COLOR, (TOTAL_WIDTH - 30, scrollbar_y, scrollbar_width, scrollbar_height))
    

    
    pygame.display.flip()

def draw_game():
    # 绘制游戏区域背景
    screen.fill((20, 20, 20))

    height = len(level)
    width = len(level[0])

    # 绘制网格线
    for y in range(height):
        for x in range(width):
            rect = (x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE)
            pygame.draw.rect(screen, (30, 30, 30), rect, 1)

    # 绘制游戏元素
    for y in range(height):
        for x in range(width):
            # 使用模型文件中的绘制函数
            draw_game_element(screen, level[y][x], x, y, TILE_SIZE)

    # 绘制右侧信息面板
    info_rect = (SCREEN_WIDTH, 0, INFO_PANEL_WIDTH, SCREEN_HEIGHT)
    pygame.draw.rect(screen, (30, 30, 30), info_rect)

    # 关卡按钮区域（5列3行，放在最上面）
    global level_buttons
    level_buttons = []
    button_w, button_h = 32, 32
    gap_x, gap_y = 10, 10
    cols, rows = 5, 3
    total_w = cols * button_w + (cols - 1) * gap_x
    total_h = rows * button_h + (rows - 1) * gap_y
    start_x = SCREEN_WIDTH + (INFO_PANEL_WIDTH - total_w) // 2
    start_y = 20  # 关卡按钮放在最上面
    font = button_font
    for i in range(15):
        row = i // cols
        col = i % cols
        x = start_x + col * (button_w + gap_x)
        y = start_y + row * (button_h + gap_y)
        rect = pygame.Rect(x, y, button_w, button_h)
        level_buttons.append((i, rect))
        
        # 判断按钮状态并设置颜色
        if i == pressed_level_button:
            # 按下状态：深蓝色背景，白色边框，深色文字
            bg_color = (60, 120, 200)  # 深蓝色
            border_color = (255, 255, 255)  # 白色边框
            text_color = (255, 255, 255)  # 白色文字
            border_width = 3  # 更粗的边框
            # 添加按下时的阴影效果
            shadow_rect = pygame.Rect(x + 2, y + 2, button_w, button_h)
            pygame.draw.rect(screen, (20, 40, 80), shadow_rect, border_radius=6)
        elif i == current_level:
            # 当前关卡：金色背景，深色边框，深色文字
            bg_color = (255, 200, 0)  # 金色
            border_color = (139, 69, 19)  # 深棕色边框
            text_color = (0, 0, 0)  # 黑色文字
            border_width = 2
        elif i == hover_level_button:
            # 悬停状态：亮蓝色背景，白色边框，深色文字
            bg_color = (100, 180, 255)  # 亮蓝色
            border_color = (255, 255, 255)  # 白色边框
            text_color = (0, 0, 0)  # 黑色文字
            border_width = 2
            
            # 添加悬停时的多层光晕效果
            # 外层光晕（更大更淡）
            outer_glow_rect = pygame.Rect(x - 4, y - 4, button_w + 8, button_h + 8)
            pygame.draw.rect(screen, (150, 200, 255, 60), outer_glow_rect, border_radius=10)
            # 中层光晕
            glow_rect = pygame.Rect(x - 2, y - 2, button_w + 4, button_h + 4)
            pygame.draw.rect(screen, (150, 200, 255, 100), glow_rect, border_radius=8)
            
            # 添加脉冲边框效果（使用时间戳创建动画）
            pulse_alpha = int(128 + 64 * abs(math.sin(pygame.time.get_ticks() / 100)))  # 脉冲动画
            pulse_color = (255, 255, 255, pulse_alpha)
            pulse_rect = pygame.Rect(x - 1, y - 1, button_w + 2, button_h + 2)
            pygame.draw.rect(screen, pulse_color, pulse_rect, 2, border_radius=7)
            
            # 添加内部渐变效果
            gradient_rect = pygame.Rect(x + 1, y + 1, button_w - 2, button_h - 2)
            pygame.draw.rect(screen, (255, 255, 255, 30), gradient_rect, border_radius=5)
            
            # 添加四角装饰
            corner_size = 3
            corner_color = (255, 255, 255, 150)
            # 左上角
            pygame.draw.circle(screen, corner_color, (x + corner_size, y + corner_size), corner_size)
            # 右上角
            pygame.draw.circle(screen, corner_color, (x + button_w - corner_size, y + corner_size), corner_size)
            # 左下角
            pygame.draw.circle(screen, corner_color, (x + corner_size, y + button_h - corner_size), corner_size)
            # 右下角
            pygame.draw.circle(screen, corner_color, (x + button_w - corner_size, y + button_h - corner_size), corner_size)
        else:
            # 普通状态：灰色背景，灰色边框，浅色文字
            bg_color = (80, 80, 80)  # 灰色
            border_color = (120, 120, 120)  # 灰色边框
            text_color = (220, 220, 220)  # 浅色文字
            border_width = 1
        
        # 绘制按钮背景
        pygame.draw.rect(screen, bg_color, rect, border_radius=6)
        # 绘制按钮边框
        pygame.draw.rect(screen, border_color, rect, border_width, border_radius=6)
        
        # 如果是悬停或按下状态，添加高光效果
        if i == hover_level_button or i == pressed_level_button:
            highlight_rect = pygame.Rect(x + 2, y + 2, button_w - 4, button_h // 3)
            pygame.draw.rect(screen, (255, 255, 255, 50), highlight_rect, border_radius=3)
        
        # 绘制按钮文字
        text = font.render(str(i+1), True, text_color)
        text_rect = text.get_rect(center=rect.center)
        # 如果是按下状态，文字稍微偏移以模拟按下效果
        if i == pressed_level_button:
            text_rect.y += 1
        screen.blit(text, text_rect)

    # 底部区域：移动步数、撤回按钮、重新开始按钮
    bottom_start_y = SCREEN_HEIGHT - 200  # 从底部开始，留出200px空间
    
    # 移动步数
    moves_text = default_font.render(f"移动步数: {moves}", True, TEXT_COLOR)
    moves_rect = moves_text.get_rect()
    moves_x = SCREEN_WIDTH + (INFO_PANEL_WIDTH - moves_rect.width) // 2
    screen.blit(moves_text, (moves_x, bottom_start_y))

    # 撤回按钮区域
    global undo_button_rect
    undo_button_width = 180
    undo_button_height = 45
    undo_button_x = SCREEN_WIDTH + (INFO_PANEL_WIDTH - undo_button_width) // 2
    undo_button_y = bottom_start_y + 40  # 移动步数下方40px
    undo_button_rect = pygame.Rect(undo_button_x, undo_button_y, undo_button_width, undo_button_height)
    is_undo_pressed = pressed_undo
    
    # 检查撤回栈是否为空
    can_undo = len(undo_stack) > 0
    
    # 设置撤回按钮的颜色和效果
    if is_undo_pressed:
        # 按下状态：深蓝色背景，白色边框，白色文字
        bg_color = (60, 120, 200)  # 深蓝色
        border_color = (255, 255, 255)  # 白色边框
        text_color = (255, 255, 255)  # 白色文字
        border_width = 3  # 更粗的边框
        # 添加按下时的阴影效果
        shadow_rect = pygame.Rect(undo_button_x + 3, undo_button_y + 3, undo_button_width, undo_button_height)
        pygame.draw.rect(screen, (20, 40, 80), shadow_rect, border_radius=8)
    elif hover_undo_button:
        # 悬停状态：亮蓝色背景，白色边框，深色文字（无论是否可撤回都使用相同效果）
        bg_color = (100, 180, 255)  # 亮蓝色
        border_color = (255, 255, 255)  # 白色边框
        text_color = (0, 0, 0)  # 黑色文字
        border_width = 2
        
        # 添加悬停时的多层光晕效果
        # 外层光晕（更大更淡）
        outer_glow_rect = pygame.Rect(undo_button_x - 4, undo_button_y - 4, undo_button_width + 8, undo_button_height + 8)
        pygame.draw.rect(screen, (150, 200, 255, 60), outer_glow_rect, border_radius=12)
        # 中层光晕
        glow_rect = pygame.Rect(undo_button_x - 3, undo_button_y - 3, undo_button_width + 6, undo_button_height + 6)
        pygame.draw.rect(screen, (150, 200, 255, 100), glow_rect, border_radius=10)
        
        # 添加脉冲边框效果
        pulse_alpha = int(128 + 64 * abs(math.sin(pygame.time.get_ticks() / 100)))  # 脉冲动画
        pulse_color = (255, 255, 255, pulse_alpha)
        pulse_rect = pygame.Rect(undo_button_x - 1, undo_button_y - 1, undo_button_width + 2, undo_button_height + 2)
        pygame.draw.rect(screen, pulse_color, pulse_rect, 2, border_radius=9)
        
        # 添加内部渐变效果
        gradient_rect = pygame.Rect(undo_button_x + 2, undo_button_y + 2, undo_button_width - 4, undo_button_height - 4)
        pygame.draw.rect(screen, (255, 255, 255, 30), gradient_rect, border_radius=6)
        
        # 添加四角装饰
        corner_size = 4
        corner_color = (255, 255, 255, 150)
        # 左上角
        pygame.draw.circle(screen, corner_color, (undo_button_x + corner_size, undo_button_y + corner_size), corner_size)
        # 右上角
        pygame.draw.circle(screen, corner_color, (undo_button_x + undo_button_width - corner_size, undo_button_y + corner_size), corner_size)
        # 左下角
        pygame.draw.circle(screen, corner_color, (undo_button_x + corner_size, undo_button_y + undo_button_height - corner_size), corner_size)
        # 右下角
        pygame.draw.circle(screen, corner_color, (undo_button_x + undo_button_width - corner_size, undo_button_y + undo_button_height - corner_size), corner_size)
    elif not can_undo:
        # 禁用状态：灰色背景，灰色边框，灰色文字
        bg_color = (50, 50, 50)  # 深灰色
        border_color = (80, 80, 80)  # 灰色边框
        text_color = (100, 100, 100)  # 灰色文字
        border_width = 2
    else:
        # 普通状态：灰色背景，灰色边框，浅色文字
        bg_color = BUTTON_BG_COLOR
        border_color = BUTTON_BORDER_COLOR
        text_color = MENU_NORMAL_COLOR
        border_width = 2
    
    # 绘制撤回按钮背景
    pygame.draw.rect(screen, bg_color, undo_button_rect, border_radius=8)
    # 绘制撤回按钮边框
    pygame.draw.rect(screen, border_color, undo_button_rect, border_width, border_radius=8)
    
    # 如果是悬停或按下状态，添加高光效果
    if hover_undo_button or is_undo_pressed:
        highlight_rect = pygame.Rect(undo_button_x + 3, undo_button_y + 3, undo_button_width - 6, undo_button_height // 3)
        pygame.draw.rect(screen, (255, 255, 255, 50), highlight_rect, border_radius=4)
    
    # 绘制撤回按钮文字
    undo_text = button_font.render("撤回", True, text_color)
    undo_text_rect = undo_text.get_rect(center=undo_button_rect.center)
    # 如果是按下状态，文字稍微偏移以模拟按下效果
    if is_undo_pressed:
        undo_text_rect.y += 1
    screen.blit(undo_text, undo_text_rect)

    # 重新开始按钮区域
    global restart_button_rect
    restart_button_width = 180
    restart_button_height = 45
    restart_button_x = SCREEN_WIDTH + (INFO_PANEL_WIDTH - restart_button_width) // 2
    restart_button_y = bottom_start_y + 100  # 撤回按钮下方60px
    restart_button_rect = pygame.Rect(restart_button_x, restart_button_y, restart_button_width, restart_button_height)
    is_restart_pressed = pressed_restart
    
    # 设置重新开始按钮的颜色和效果
    if is_restart_pressed:
        # 按下状态：深绿色背景，白色边框，白色文字
        bg_color = (60, 150, 100)  # 深绿色
        border_color = (255, 255, 255)  # 白色边框
        text_color = (255, 255, 255)  # 白色文字
        border_width = 3  # 更粗的边框
        # 添加按下时的阴影效果
        shadow_rect = pygame.Rect(restart_button_x + 3, restart_button_y + 3, restart_button_width, restart_button_height)
        pygame.draw.rect(screen, (20, 60, 40), shadow_rect, border_radius=8)
    elif hover_restart_button:
        # 悬停状态：亮绿色背景，白色边框，深色文字
        bg_color = (100, 200, 150)  # 亮绿色
        border_color = (255, 255, 255)  # 白色边框
        text_color = (0, 0, 0)  # 黑色文字
        border_width = 2
        
        # 添加悬停时的多层光晕效果
        # 外层光晕（更大更淡）
        outer_glow_rect = pygame.Rect(restart_button_x - 4, restart_button_y - 4, restart_button_width + 8, restart_button_height + 8)
        pygame.draw.rect(screen, (150, 220, 180, 60), outer_glow_rect, border_radius=12)
        # 中层光晕
        glow_rect = pygame.Rect(restart_button_x - 3, restart_button_y - 3, restart_button_width + 6, restart_button_height + 6)
        pygame.draw.rect(screen, (150, 220, 180, 100), glow_rect, border_radius=10)
        
        # 添加脉冲边框效果
        pulse_alpha = int(128 + 64 * abs(math.sin(pygame.time.get_ticks() / 100)))  # 脉冲动画
        pulse_color = (255, 255, 255, pulse_alpha)
        pulse_rect = pygame.Rect(restart_button_x - 1, restart_button_y - 1, restart_button_width + 2, restart_button_height + 2)
        pygame.draw.rect(screen, pulse_color, pulse_rect, 2, border_radius=9)
        
        # 添加内部渐变效果
        gradient_rect = pygame.Rect(restart_button_x + 2, restart_button_y + 2, restart_button_width - 4, restart_button_height - 4)
        pygame.draw.rect(screen, (255, 255, 255, 30), gradient_rect, border_radius=6)
        
        # 添加四角装饰
        corner_size = 4
        corner_color = (255, 255, 255, 150)
        # 左上角
        pygame.draw.circle(screen, corner_color, (restart_button_x + corner_size, restart_button_y + corner_size), corner_size)
        # 右上角
        pygame.draw.circle(screen, corner_color, (restart_button_x + restart_button_width - corner_size, restart_button_y + corner_size), corner_size)
        # 左下角
        pygame.draw.circle(screen, corner_color, (restart_button_x + corner_size, restart_button_y + restart_button_height - corner_size), corner_size)
        # 右下角
        pygame.draw.circle(screen, corner_color, (restart_button_x + restart_button_width - corner_size, restart_button_y + restart_button_height - corner_size), corner_size)
    else:
        # 普通状态：灰色背景，灰色边框，浅色文字
        bg_color = BUTTON_BG_COLOR
        border_color = BUTTON_BORDER_COLOR
        text_color = MENU_NORMAL_COLOR
        border_width = 2
    
    # 绘制重新开始按钮背景
    pygame.draw.rect(screen, bg_color, restart_button_rect, border_radius=8)
    # 绘制重新开始按钮边框
    pygame.draw.rect(screen, border_color, restart_button_rect, border_width, border_radius=8)
    
    # 如果是悬停或按下状态，添加高光效果
    if hover_restart_button or is_restart_pressed:
        highlight_rect = pygame.Rect(restart_button_x + 3, restart_button_y + 3, restart_button_width - 6, restart_button_height // 3)
        pygame.draw.rect(screen, (255, 255, 255, 50), highlight_rect, border_radius=4)
    
    # 绘制重新开始按钮文字
    restart_text = button_font.render("重新开始", True, text_color)
    restart_text_rect = restart_text.get_rect(center=restart_button_rect.center)
    # 如果是按下状态，文字稍微偏移以模拟按下效果
    if is_restart_pressed:
        restart_text_rect.y += 1
    screen.blit(restart_text, restart_text_rect)
    
    pygame.display.flip()

def move_player(dx, dy):
    global player_pos, moves
    if player_pos is None:
        return
    x, y = player_pos
    new_x, new_y = x + dx, y + dy
    next_x, next_y = new_x + dx, new_y + dy

    height = len(level)
    width = len(level[0])

    # 检查是否在地图范围内
    if new_x < 0 or new_x >= width or new_y < 0 or new_y >= height:
        return

    # 获取当前格子和目标格子的值
    current = level[y][x]
    target = level[new_y][new_x]

    # 检查移动是否有效
    valid_move = False
    
    # 如果目标位置是可移动的，直接移动
    if is_movable(target):
        valid_move = True
    # 如果目标位置是可推动的箱子
    elif is_pushable(target):
        if next_x >= 0 and next_x < width and next_y >= 0 and next_y < height:
            next_cell = level[next_y][next_x]
            if is_movable(next_cell):
                valid_move = True
    
    # 只有在移动有效时才保存撤回状态
    if valid_move:
        save_undo_state()

    # 执行移动
    if is_movable(target):
        # 如果目标位置是可移动的，直接移动
        level[y][x] = TARGET if current == PLAYER_ON_TARGET else PATH
        level[new_y][new_x] = PLAYER if target == PATH else PLAYER_ON_TARGET
        player_pos = (new_x, new_y)
        moves += 1
        draw_game()
        check_game_over()
        return
    elif is_pushable(target):
        # 如果目标位置是可推动的箱子
        if next_x >= 0 and next_x < width and next_y >= 0 and next_y < height:
            next_cell = level[next_y][next_x]
            if is_movable(next_cell):
                level[next_y][next_x] = BOX if next_cell == PATH else BOX_ON_TARGET
                level[new_y][new_x] = PLAYER if target == BOX else PLAYER_ON_TARGET
                if current == PLAYER:
                    level[y][x] = PATH
                else:
                    level[y][x] = TARGET
                player_pos = (new_x, new_y)
                moves += 1
                draw_game()
                check_game_over()
                return
    
    # 如果移动无效，重新绘制界面
    draw_game()

# 优化胜利判定，立即弹窗

def check_game_over():
    boxes_on_target = 0
    total_boxes = 0
    height = len(level)
    width = len(level[0])
    for y in range(height):
        for x in range(width):
            element_type = level[y][x]
            if element_type == BOX:
                total_boxes += 1
            elif element_type == BOX_ON_TARGET:
                total_boxes += 1
                boxes_on_target += 1
    if total_boxes > 0 and boxes_on_target == total_boxes:
        show_game_over()
        return True
    return False

def show_game_over():
    # 切换到胜利弹窗状态
    global game_state
    game_state = GAME_STATE_VICTORY
    hover_victory_option = -1  # 重置悬停状态
    draw_victory_popup()

def next_level():
    global current_level
    current_level += 1
    reset_current_level()

def prev_level():
    global current_level
    current_level -= 1
    reset_current_level()

def reset_current_level():
    global level, player_pos, moves, background_cache
    level, player_pos = reset_level()
    moves = 0
    background_cache = None  # 清除背景缓存
    draw_game()

def start_game():
    """开始游戏"""
    global game_state, current_level, selected_level
    current_level = selected_level
    reset_current_level()
    game_state = GAME_STATE_PLAYING

# 初始化显示菜单
menu_buttons = draw_menu(screen, TOTAL_WIDTH, SCREEN_HEIGHT)

# 主游戏循环
while running:
    # 检查窗口激活状态
    if not pygame.display.get_active():
        pygame.display.set_caption("推箱子游戏 - 请点击窗口激活")
    else:
        pygame.display.set_caption("推箱子游戏")
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False



        elif event.type == pygame.MOUSEBUTTONUP:
            # 鼠标释放事件
            if event.button == 1:  # 左键释放
                if game_state == GAME_STATE_RULES and scrollbar_dragging:
                    # 结束滚动条拖动
                    scrollbar_dragging = False
                    drag_start_y = 0
                    drag_start_offset = 0
                elif game_state == GAME_STATE_PLAYING:
                    # 处理按钮释放
                    mouse_x, mouse_y = pygame.mouse.get_pos()
                    if pressed_undo:
                        if undo_button_rect and undo_button_rect.collidepoint(mouse_x, mouse_y):
                            pressed_undo = False
                            # 检查撤回栈是否为空，只有在不为空时才执行撤回操作
                            if undo_stack:
                                undo_move()
                            # 无论是否执行撤回操作，都重新绘制界面
                            draw_game()
                        else:
                            pressed_undo = False
                            draw_game()
                    elif pressed_restart:
                        pressed_restart = False
                        reset_current_level()
                    elif pressed_level_button != -1:
                        idx = pressed_level_button
                        pressed_level_button = -1
                        if idx != current_level:
                            current_level = idx
                            selected_level = idx
                            reset_level()
                            moves = 0
                            background_cache = None  # 清除背景缓存
                    draw_game()  # 重绘界面

        elif event.type == pygame.MOUSEBUTTONDOWN:
            # 只处理鼠标左键点击（button == 1）
            if event.button != 1:
                continue
            if game_state == GAME_STATE_PLAYING:
                mouse_x, mouse_y = pygame.mouse.get_pos()
                # 撤回按钮
                if undo_button_rect and undo_button_rect.collidepoint(mouse_x, mouse_y):
                    pressed_undo = True
                    draw_game()
                    continue
                # 重新开始按钮
                if restart_button_rect and restart_button_rect.collidepoint(mouse_x, mouse_y):
                    pressed_restart = True
                    draw_game()
                    continue
                # 关卡按钮
                for idx, rect in level_buttons:
                    if rect.collidepoint(mouse_x, mouse_y):
                        pressed_level_button = idx
                        draw_game()
                        break
            elif game_state == GAME_STATE_MENU:
                # 主菜单鼠标点击
                result = handle_menu_click(event.pos, menu_buttons)
                if result == "start":
                    # 开始游戏 - 初始化到第一关
                    current_level = 0  # 设置为第一关
                    selected_level = 0  # 设置选中关卡为第一关
                    game_state = GAME_STATE_PLAYING
                    # 重置游戏状态
                    level, player_pos = reset_level()
                    moves = 0  # 重置移动步数
                    # 清空撤回栈
                    undo_stack.clear()
                    background_cache = None  # 清除背景缓存
                    draw_game()
                elif result == "rules":
                    # 显示游戏规则
                    game_state = GAME_STATE_RULES
                    rules_scroll_offset = 0
                    rules_from_pause = False
                    draw_rules()
                elif result == "exit":
                    # 显示退出确认
                    game_state = GAME_STATE_EXIT_CONFIRM
                    exit_confirm_selection = 0
                    exit_from_menu = True
                    exit_from_pause = False
                    draw_exit_confirm()
            elif game_state == GAME_STATE_PAUSED:
                # 暂停菜单鼠标点击
                mouse_x, mouse_y = pygame.mouse.get_pos()
                # 检查是否点击了菜单项
                for i in range(3):
                    menu_y = SCREEN_HEIGHT // 2 - 30 + i * 50
                    if mouse_y >= menu_y - 20 and mouse_y <= menu_y + 20:
                        selected_pause_item = i
                        hover_pause_item = i  # 点击时设置悬停状态
                        if i == 0:  # 继续游戏
                            game_state = GAME_STATE_PLAYING
                            draw_game()
                        elif i == 1:  # 游戏规则
                            game_state = GAME_STATE_RULES
                            rules_scroll_offset = 0
                            rules_from_pause = True
                            draw_rules()
                        elif i == 2:  # 退出游戏
                            game_state = GAME_STATE_EXIT_CONFIRM
                            exit_confirm_selection = 0
                            exit_from_pause = True
                            exit_from_menu = False
                            draw_exit_confirm()
                        break
            elif game_state == GAME_STATE_RULES:
                # 鼠标点击处理 - 处理返回按钮和滚动条点击
                mouse_x, mouse_y = pygame.mouse.get_pos()
                
                # 检查是否点击了返回按钮
                button_width = 80
                button_height = 30
                button_x = 20
                button_y = 35
                if (button_x <= mouse_x <= button_x + button_width and 
                    button_y <= mouse_y <= button_y + button_height):
                    # 点击了返回按钮
                    if rules_from_pause:
                        game_state = GAME_STATE_PAUSED
                        draw_pause_menu()
                    else:
                        # 返回到菜单界面
                        game_state = GAME_STATE_MENU
                        draw_menu(screen, TOTAL_WIDTH, SCREEN_HEIGHT)
                    continue
                
                # 检查是否点击了滚动条
                if mouse_x >= TOTAL_WIDTH - 30 and mouse_x <= TOTAL_WIDTH - 20 and mouse_y >= 100 and mouse_y <= SCREEN_HEIGHT - 50:
                    # 计算滚动条点击位置
                    rules = get_rules_content()
                    rule_height = len(rules) * 35  # 调整行间距
                    max_scroll = max(0, rule_height - (SCREEN_HEIGHT - 200))
                    if max_scroll > 0:
                        # 开始拖动滚动条
                        scrollbar_dragging = True
                        drag_start_y = mouse_y
                        drag_start_offset = rules_scroll_offset
                        
                        # 计算点击位置对应的滚动偏移
                        scroll_area_height = SCREEN_HEIGHT - 200
                        click_ratio = (mouse_y - 100) / scroll_area_height
                        rules_scroll_offset = int(click_ratio * max_scroll)
                        draw_rules()
                # 其他点击无任何操作
            elif game_state == GAME_STATE_EXIT_CONFIRM:
                # 退出确认界面鼠标点击
                mouse_x, mouse_y = pygame.mouse.get_pos()
                # 检查是否点击了选项
                for i in range(2):
                    option_x = TOTAL_WIDTH // 2 - 50 + i * 100
                    if mouse_x >= option_x - 30 and mouse_x <= option_x + 30 and mouse_y >= SCREEN_HEIGHT // 2 and mouse_y <= SCREEN_HEIGHT // 2 + 40:
                        exit_confirm_selection = i
                        hover_exit_option = i  # 点击时设置悬停状态
                        if i == 0:  # 是
                            if exit_from_menu:
                                # 从菜单界面退出，直接关闭游戏
                                running = False
                            else:
                                # 从游戏界面退出，返回到初始化菜单
                                game_state = GAME_STATE_MENU
                                draw_menu(screen, TOTAL_WIDTH, SCREEN_HEIGHT)
                        else:  # 否
                            if exit_from_menu:
                                # 从菜单界面取消退出，重新显示菜单
                                game_state = GAME_STATE_MENU
                                draw_menu(screen, TOTAL_WIDTH, SCREEN_HEIGHT)
                            elif exit_from_pause:
                                game_state = GAME_STATE_PAUSED
                                draw_pause_menu()
                            else:
                                game_state = GAME_STATE_PLAYING
                                draw_game()
                        break
            elif game_state == GAME_STATE_VICTORY:
                # 胜利弹窗界面鼠标点击
                mouse_x, mouse_y = pygame.mouse.get_pos()
                # 检查是否点击了选项
                for i in range(2):
                    option_x = TOTAL_WIDTH // 2 - 80 + i * 160
                    if mouse_x >= option_x - 30 and mouse_x <= option_x + 30 and mouse_y >= SCREEN_HEIGHT // 2 + 80 and mouse_y <= SCREEN_HEIGHT // 2 + 120:
                        hover_victory_option = i  # 点击时设置悬停状态
                        if i == 0:  # 是 - 进入下一关
                            if current_level < len(levels) - 1:
                                next_level()
                                game_state = GAME_STATE_PLAYING
                                draw_game()
                            else:
                                # 已经是最后一关，重新开始本关
                                reset_current_level()
                                game_state = GAME_STATE_PLAYING
                                draw_game()
                        else:  # 否 - 重新玩本关
                            reset_current_level()
                            game_state = GAME_STATE_PLAYING
                            draw_game()
                        break

        elif event.type == pygame.MOUSEMOTION:
            mouse_x, mouse_y = pygame.mouse.get_pos()
            
            # 处理滚动条拖动
            if game_state == GAME_STATE_RULES and scrollbar_dragging:
                rules = get_rules_content()
                rule_height = len(rules) * 35
                max_scroll = max(0, rule_height - (SCREEN_HEIGHT - 200))
                if max_scroll > 0:
                    # 计算拖动距离对应的滚动偏移
                    scroll_area_height = SCREEN_HEIGHT - 200
                    drag_distance = mouse_y - drag_start_y
                    drag_ratio = drag_distance / scroll_area_height
                    new_offset = drag_start_offset + int(drag_ratio * max_scroll)
                    
                    # 限制滚动范围
                    rules_scroll_offset = max(0, min(max_scroll, new_offset))
                    draw_rules()
                    continue
            
            # 处理游戏界面的关卡按钮悬停
            if game_state == GAME_STATE_PLAYING:
                old_hover = hover_level_button
                hover_level_button = -1
                for idx, rect in level_buttons:
                    if rect.collidepoint(mouse_x, mouse_y):
                        hover_level_button = idx
                        break
                if old_hover != hover_level_button:
                    draw_game()
                
                # 处理撤回和重新开始按钮的悬停检测
                # 撤回按钮悬停检测
                old_undo_hover = hover_undo_button
                hover_undo_button = False
                if undo_button_rect and undo_button_rect.collidepoint(mouse_x, mouse_y):
                    hover_undo_button = True
                
                # 重新开始按钮悬停检测
                old_restart_hover = hover_restart_button
                hover_restart_button = False
                if restart_button_rect and restart_button_rect.collidepoint(mouse_x, mouse_y):
                    hover_restart_button = True
                
                # 只在悬停状态改变时重绘
                if old_undo_hover != hover_undo_button or old_restart_hover != hover_restart_button:
                    draw_game()
            
            elif game_state == GAME_STATE_MENU:
                # 主菜单悬停处理 - 只在状态改变时重绘
                old_hover = hover_menu_item
                hover_menu_item = -1
                for i, (action, button_rect) in enumerate(menu_buttons):
                    if button_rect.collidepoint(mouse_x, mouse_y):
                        hover_menu_item = i
                        break
                if old_hover != hover_menu_item:
                    menu_buttons = draw_menu(screen, TOTAL_WIDTH, SCREEN_HEIGHT)
                    
            elif game_state == GAME_STATE_PAUSED:
                # 检查暂停菜单悬停 - 优化防闪烁
                old_hover = hover_pause_item
                hover_pause_item = -1
                for i in range(3):
                    menu_y = SCREEN_HEIGHT // 2 - 30 + i * 50
                    if mouse_y >= menu_y - 20 and mouse_y <= menu_y + 20:
                        hover_pause_item = i
                        break
                # 只在悬停状态真正改变时才重绘
                if old_hover != hover_pause_item:
                    draw_pause_menu()
                    
            elif game_state == GAME_STATE_RULES:
                # 规则界面悬停处理 - 优化防闪烁
                button_width = 80
                button_height = 30
                button_x = 20
                button_y = 35
                old_hover = hover_menu_item
                hover_menu_item = -1
                if (button_x <= mouse_x <= button_x + button_width and 
                    button_y <= mouse_y <= button_y + button_height):
                    hover_menu_item = 0
                # 只在悬停状态真正改变时才重绘
                if old_hover != hover_menu_item:
                    draw_rules()
                    
            elif game_state == GAME_STATE_EXIT_CONFIRM:
                # 检查退出确认悬停 - 优化防闪烁
                old_hover = hover_exit_option
                hover_exit_option = -1
                for i in range(2):
                    option_x = TOTAL_WIDTH // 2 - 50 + i * 100
                    if mouse_x >= option_x - 30 and mouse_x <= option_x + 30 and mouse_y >= SCREEN_HEIGHT // 2 and mouse_y <= SCREEN_HEIGHT // 2 + 40:
                        hover_exit_option = i
                        break
                # 只在悬停状态真正改变时才重绘
                if old_hover != hover_exit_option:
                    draw_exit_confirm()
            elif game_state == GAME_STATE_VICTORY:
                # 检查胜利弹窗悬停 - 优化防闪烁
                old_hover = hover_victory_option
                hover_victory_option = -1
                for i in range(2):
                    option_x = TOTAL_WIDTH // 2 - 80 + i * 160
                    if mouse_x >= option_x - 30 and mouse_x <= option_x + 30 and mouse_y >= SCREEN_HEIGHT // 2 + 80 and mouse_y <= SCREEN_HEIGHT // 2 + 120:
                        hover_victory_option = i
                        break
                # 只在悬停状态真正改变时才重绘
                if old_hover != hover_victory_option:
                    draw_victory_popup()

        elif event.type == pygame.MOUSEWHEEL:
            if game_state == GAME_STATE_RULES:
                # 规则界面鼠标滚轮滚动
                rules = get_rules_content()
                rule_height = len(rules) * 35  # 调整行间距
                max_scroll = max(0, rule_height - (SCREEN_HEIGHT - 200))
                if max_scroll > 0:
                    # 滚轮向上滚动（y > 0）时向上滚动内容，向下滚动（y < 0）时向下滚动内容
                    rules_scroll_offset = max(0, min(max_scroll, rules_scroll_offset - event.y * 35))
                    draw_rules()

        elif event.type == pygame.KEYDOWN:
            if game_state == GAME_STATE_PLAYING:
                # 游戏进行中
                if event.key == pygame.K_ESCAPE:
                    game_state = GAME_STATE_PAUSED
                    selected_pause_item = 0
                    draw_pause_menu()
                elif event.key in [pygame.K_UP, pygame.K_w]:
                    move_player(0, -1)
                elif event.key in [pygame.K_DOWN, pygame.K_s]:
                    move_player(0, 1)
                elif event.key in [pygame.K_LEFT, pygame.K_a]:
                    move_player(-1, 0)
                elif event.key in [pygame.K_RIGHT, pygame.K_d]:
                    move_player(1, 0)
                elif event.key == pygame.K_r:
                    reset_current_level()
                elif event.key == pygame.K_n and current_level < len(levels) - 1:
                    next_level()
                    draw_game() # 只在切换关卡后调用draw_game()
                elif event.key == pygame.K_p and current_level > 0:
                    prev_level()
                    draw_game() # 只在切换关卡后调用draw_game()
                elif event.key == pygame.K_q:
                    game_state = GAME_STATE_EXIT_CONFIRM
                    exit_confirm_selection = 0
                    exit_from_pause = False
                    exit_from_menu = False
                    draw_exit_confirm()
                # 关卡选择功能
                elif event.key == pygame.K_LEFT and pygame.key.get_mods() & pygame.KMOD_CTRL:
                    selected_level = max(0, selected_level - 1)
                    draw_game()
                elif event.key == pygame.K_RIGHT and pygame.key.get_mods() & pygame.KMOD_CTRL:
                    selected_level = min(len(levels) - 1, selected_level + 1)
                    draw_game()
                elif event.key == pygame.K_RETURN:
                    # 确认选择关卡
                    if selected_level != current_level:
                        current_level = selected_level
                        level, player_pos = reset_level()
                        moves = 0
                        background_cache = None  # 清除背景缓存
                        draw_game()
    
    # 控制帧率
    clock.tick(60)

pygame.quit()
sys.exit()
